﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.iss.inventory.Entity;
using com.iss.inventory.CustomModels;
using System.Web;
using com.iss.inventory.BusinessLogic;

namespace com.iss.inventory.Controllers
{
    public class StationeryRetrievalController
    {
        InvManagementEntities ime = new InvManagementEntities();
        
        public customSRFDetailsModel getIncompleteRequestsforSRF()
        {
            InvManagementEntities em = new InvManagementEntities();
            List<RequestDetail> rqDetList;
                var incompleteRequestsList = from req in em.RequestDetails
                                             where (req.RequestList.Status == "Approved") || (req.RequestList.Status == "DeliveryInProgress")
                                             orderby req.ItemID, req.RequestList.Status, req.RequestList.DateReceived
                                             select req;

                //request details ordered by item, status and approved date
                rqDetList = incompleteRequestsList.ToList<RequestDetail>();
            
            List<RequestListSuggestionModel> rqDetSugList = new List<RequestListSuggestionModel>();
            
            foreach (RequestDetail temp_rd in rqDetList)
            {
                //RequestListSuggestionModel model = new RequestListSuggestionModel();
                //model.setReqDetail(temp_rd);
                //int temp_sugQty = Convert.ToInt32(temp_rd.QtyRequested - temp_rd.QtyDelivered);
                ////initially suggested amount is based on outstanding qty of each req details
                //model.setSuggestionQty(temp_sugQty);
                //rqDetSugList.Add(model);
                int temp_sugQty = Convert.ToInt32(temp_rd.QtyRequested - temp_rd.QtyDelivered);
                if (temp_sugQty > 0)
                {
                    RequestListSuggestionModel model = new RequestListSuggestionModel();
                    model.setReqDetail(temp_rd);
                    //initially suggested amount is based on outstanding qty of each req details
                    model.setSuggestionQty(temp_sugQty);
                    rqDetSugList.Add(model);
                }
            }

            if (rqDetSugList.Count == 0)
                return null;

            int temp_itemId = Convert.ToInt32(rqDetSugList[0].getReqDetail().StationeryItem.ItemID);
            int temp_itemAvailQty = Convert.ToInt32(rqDetSugList[0].getReqDetail().StationeryItem.QtyLeft);
            //check suggestion qty
            foreach (RequestListSuggestionModel temp_rds in rqDetSugList)
            {
                if (temp_itemId != temp_rds.getReqDetail().StationeryItem.ItemID)//for next item
                {
                    temp_itemId = temp_rds.getReqDetail().StationeryItem.ItemID;
                    temp_itemAvailQty = (int)temp_rds.getReqDetail().StationeryItem.QtyLeft;
                }

                if (temp_rds.getSuggestionQty() <= temp_itemAvailQty) //if sufficient stock available
                    temp_itemAvailQty -= temp_rds.getSuggestionQty();
                else  //if insufficient stock, set available stock to zero and give all to existing reqdet
                {
                    temp_rds.setSuggestionQty(temp_itemAvailQty);
                    temp_itemAvailQty = 0;
                }
            }

            //re-order list to suit display by department
            //order by item,department,status and approved date
            var temp_rqds = from r in rqDetSugList
                            orderby r.getReqDetail().StationeryItem.ItemID, r.getReqDetail().RequestList.Employee.DeptID, r.getReqDetail().RequestList.Status, r.getReqDetail().RequestList.DateReceived
                            select r;
            rqDetSugList = temp_rqds.ToList<RequestListSuggestionModel>();
            List<SRFRequestDetailsModel> srfRequestDetailsModelList = new List<SRFRequestDetailsModel>();
            List<SRFDetail> unsaved_SrfDetailsList = new List<SRFDetail>();
            customSRFDetailsModel customSRFModel = new customSRFDetailsModel();
            //create SRF Details from requestDetails list
            int temp_itemID = 0;
            int temp_deptID = 0;
            SRFDetail temp_srfDetail = new SRFDetail();
            SRFRequestDetailsModel temp_srfrdm = new SRFRequestDetailsModel();
            foreach (RequestListSuggestionModel temp_rds in rqDetSugList)
            {
                SRFRequestDetail temp_srfrd = new SRFRequestDetail();


                if (!((temp_itemID == temp_rds.getReqDetail().ItemID) && (temp_deptID == temp_rds.getReqDetail().RequestList.Employee.DeptID)))
                {
                    //for creating new SRF Details row
                    temp_srfDetail = new SRFDetail();
                    temp_srfDetail.Department = temp_rds.getReqDetail().RequestList.Employee.Department;
                    temp_srfrdm = new SRFRequestDetailsModel();
                    temp_srfrdm.SrfDetail = temp_srfDetail;
                    temp_srfrdm.RequestDetails.Add(temp_rds.getReqDetail());
                    temp_srfrd.SRFDetail = temp_srfDetail;
                    temp_srfrd.RequestDetail = temp_rds.getReqDetail();
                    temp_srfDetail.Status = "new"; //list is not yet saved into database
                    temp_srfDetail.StationeryItem = temp_rds.getReqDetail().StationeryItem;
                    temp_srfDetail.QtyRequested = temp_rds.getReqDetail().QtyRequested - temp_rds.getReqDetail().QtyDelivered;
                    temp_srfDetail.QtyRetrieved = temp_rds.getSuggestionQty();
                    temp_srfDetail.CollectionPt = temp_srfDetail.Department.CollectionPoint;
                    temp_srfDetail.CollectionDateTime = System.DateTime.Now.AddDays(7); //needs algorithm to add upto specific day
                    temp_srfDetail.RepresentativeID = temp_srfDetail.Department.RepresentativeID;
                    unsaved_SrfDetailsList.Add(temp_srfDetail);
                    temp_itemID = Convert.ToInt32(temp_srfDetail.ItemID);
                    temp_deptID = Convert.ToInt32(temp_srfDetail.DeptID);
                }
                else
                {
                    //for existing SRF Details row
                    int temp_qty = Convert.ToInt32(temp_rds.getReqDetail().QtyRequested - temp_rds.getReqDetail().QtyDelivered);
                    temp_srfDetail.QtyRequested += temp_qty;
                    temp_srfrdm.RequestDetails.Add(temp_rds.getReqDetail());
                    temp_srfrd.SRFDetail = temp_srfDetail;
                    temp_srfrd.RequestDetail = temp_rds.getReqDetail();
                    int temp_retQty = temp_rds.getSuggestionQty();
                    temp_srfDetail.QtyRetrieved += temp_retQty;
                }
                //add SRF Request detail for each request detail into database
                //srfrd.SRFDetail = temp_srfDetail;
                //srfrd.RequestDetail = temp_rds.getReqDetail();
                //em.AddToSRFRequestDetails(temp_srfrd);
                srfRequestDetailsModelList.Add(temp_srfrdm);

            }
            customSRFModel.srfDetailsList = unsaved_SrfDetailsList;
            customSRFModel.srfRequestDetailsModelsList = srfRequestDetailsModelList;
            return customSRFModel;
        }

        //SRF Details are only saved and a form number is generated, no changes to request details
        public int saveSrfDetails(customSRFDetailsModel customSRFModel,int createdByEmpId)
        {
            InvManagementEntities em = new InvManagementEntities();
            SRF srf;
            if (customSRFModel.srfDetailsList[0].SRFID.Equals(null))
                srf = new SRF();
            else srf = customSRFModel.srfDetailsList[0].SRF;

            srf.RFDate = System.DateTime.Now;
            srf.Employee = em.Employees.Where(x=>x.EmployeeID== createdByEmpId).FirstOrDefault();
            srf.StatusforForm = "Created"; //list is not disbursed now, hence request details are not updated
            
            em.AddToSRFs(srf);
            em.SaveChanges();
            var q = from s in em.SRFs
                    select s;
            srf = q.ToList<SRF>().LastOrDefault();
            int i = 0;
            foreach (SRFDetail srfd in customSRFModel.srfDetailsList)
            {
                SRFRequestDetailsModel srfRequestDetailsModel = new SRFRequestDetailsModel();
                SRFDetail newsrfdetail = new SRFDetail();
                newsrfdetail.SRFID = srf.SRFID;
                newsrfdetail.DeptID = srfd.DeptID;
                newsrfdetail.Status = srfd.Status;
                newsrfdetail.ItemID = srfd.ItemID;
                newsrfdetail.QtyRequested = srfd.QtyRequested;
                newsrfdetail.QtyRetrieved = srfd.QtyRetrieved;
                newsrfdetail.CollectionPt = srfd.CollectionPt;
                newsrfdetail.CollectionDateTime = srfd.CollectionDateTime;
                newsrfdetail.RepresentativeID = srfd.RepresentativeID;
                em.SRFDetails.AddObject(newsrfdetail);
                em.SaveChanges();
                var temp_q = from s in em.SRFDetails
                             select s;
                SRFDetail temp_srfd = temp_q.ToList<SRFDetail>().LastOrDefault();
                List<RequestDetail> temp_rdsrfd = customSRFModel.srfRequestDetailsModelsList[i].RequestDetails;
                i++;
                foreach (RequestDetail temp_rd in temp_rdsrfd)
                {
                    SRFRequestDetail temp_srfrd = new SRFRequestDetail();
                    temp_srfrd.SRFDetailsID = temp_srfd.SRFDetailsID;
                    temp_srfrd.RequestDetailsID = temp_rd.RequestDetailsID;
                    em.AddToSRFRequestDetails(temp_srfrd);
                    em.SaveChanges();
                }
            }
            return srf.SRFID;
            //return true;
        }

        public SRF getSRF(int srfId)
        {
            InvManagementEntities em = new InvManagementEntities();
            
            return em.SRFs.Where(x=>x.SRFID==srfId).FirstOrDefault();
        }

        public List<SRFDetail> getSRFDetails_bySRFID(int srfId)
        {
            InvManagementEntities em = new InvManagementEntities();
            return em.SRFDetails.Where(x => x.SRFID == srfId).ToList<SRFDetail>();
        }


        public void updateStationeryRequestFormsStatus(List<RequestDetail> requestDetailsList)
        {
            InvManagementEntities em = new InvManagementEntities();
            var temp_reqList = requestDetailsList.Select(r=>r.RequestList).Distinct();

            List<RequestList> reqList = temp_reqList.ToList<RequestList>();

            foreach (RequestList rl in reqList)
            {
                bool isIncomplete = false;
                foreach (RequestDetail rd in rl.RequestDetails)
                {
                    if (rd.QtyRequested != rd.QtyDelivered)
                    {
                        isIncomplete = true;
                        break;
                    }
                }
                RequestList reql = em.RequestLists.Where(x => x.RequestID == rl.RequestID).FirstOrDefault();
                if (!isIncomplete) reql.Status = "Delivered";
                em.SaveChanges();
            }
        }

        public bool generateDisbursementList(List<SRFDetail> srfDetailsList)  //need to write the code further, after confirming with ben
        {
            InvManagementEntities em = new InvManagementEntities();
            
            //4 stages:
            //1.update stock card of all items
            //2a.get request details of all stationery retrievals and update using suggestion logic
            //2b.update request IDs status as per delivery completed
            //3.change srf status to disbursed
            //4.send e-mail to all concerned employees of the latest disbursement list (need new function)
            int totalQtyPerItem = 0;
            int prevItem = 0;
            foreach (SRFDetail l_srfd in srfDetailsList)
            {
                if (prevItem == l_srfd.ItemID) //same item
                {
                    totalQtyPerItem += Convert.ToInt32(l_srfd.QtyRetrieved);
                }
                else //new item
                {
                    totalQtyPerItem = Convert.ToInt32(l_srfd.QtyRetrieved);
                }
                StationeryItem item = em.StationeryItems.FirstOrDefault(x => x.ItemID == l_srfd.ItemID);
                int qtyLeft = Convert.ToInt32(item.QtyLeft); // gets latest quantity of item
                prevItem = Convert.ToInt32(l_srfd.ItemID);
                if (qtyLeft < totalQtyPerItem)
                    return false;
            }

            foreach (SRFDetail l_srfd in srfDetailsList)
            {
                SRFDetail srfd = em.SRFDetails.Where(x => x.SRFDetailsID == l_srfd.SRFDetailsID).FirstOrDefault();
                srfd.Department = em.Departments.Where(x => x.DeptID == srfd.DeptID).FirstOrDefault();
                //srfd.DeptID = l_srfd.DeptID;
                srfd.CollectionPt = srfd.Department.CollectionPoint;
                string collpt = srfd.Department.CollectionPoint;

                if (collpt == "Engineering School") srfd.CollectionDateTime = CollectionPoint.Engineering;
                else if (collpt == "Unversity Hospital") srfd.CollectionDateTime = CollectionPoint.Hospital;
                else if (collpt == "Management School") srfd.CollectionDateTime = CollectionPoint.Management;
                else if (collpt == "Medical School") srfd.CollectionDateTime = CollectionPoint.Medical;
                else if (collpt == "Science Dept") srfd.CollectionDateTime = CollectionPoint.Science;
                else srfd.CollectionDateTime = CollectionPoint.Store;

                //srfd.CollectionDateTime = System.DateTime.Now.AddDays(7); //needs algorithm to add upto specific day
                srfd.RepresentativeID = srfd.Department.RepresentativeID;
                srfd.QtyRetrieved = l_srfd.QtyRetrieved;
                StationeryItem item = em.StationeryItems.FirstOrDefault(x => x.ItemID == srfd.ItemID);
                item.QtyLeft -= l_srfd.QtyRetrieved;

                em.SaveChanges();

                //order request details of particular srf details by status and date
                var temp_ReqDetList = from s in em.SRFRequestDetails
                                         where s.SRFDetailsID == srfd.SRFDetailsID
                                         orderby s.RequestDetail.RequestList.Status, s.RequestDetail.RequestList.DateReceived
                                          select s.RequestDetail;
                List<RequestDetail> requestDetailsList = temp_ReqDetList.ToList<RequestDetail>();

                int temp_srfdqty = Convert.ToInt32(srfd.QtyRetrieved);
                
                //update request details qty as requested with retrieved qty
                foreach (RequestDetail l_rd in requestDetailsList)
                {
                    RequestDetail rd = em.RequestDetails.Where(x => x.RequestDetailsID == l_rd.RequestDetailsID).FirstOrDefault();

                    int temp_rdQty = Convert.ToInt32(rd.QtyRequested - rd.QtyDelivered);
                    if (temp_srfdqty >= temp_rdQty) // sufficient stock available
                    {
                        rd.QtyDelivered = rd.QtyRequested;
                        temp_srfdqty -= temp_rdQty;
                    }
                    else //insufficient stock available
                    {
                        rd.QtyDelivered += temp_srfdqty;
                        temp_srfdqty = 0;
                    }

                    em.SaveChanges();

                }

                //check for updating Stationery Request Form Status
                updateStationeryRequestFormsStatus(requestDetailsList);
            }
            int srfId = Convert.ToInt32(srfDetailsList[0].SRFID);
            SRF srf = em.SRFs.Where(x=>x.SRFID == srfId).FirstOrDefault();
            srf.StatusforForm = "Disbursed";

            em.SaveChanges();
            return true;
            //send e-mails
            //foreach (SRFDetail srfd in srfDetailsList)
            //{
            //    int headID = Convert.ToInt32(srfd.Department.HeadID);
            //    int representativeID = Convert.ToInt32(srfd.Department.RepresentativeID);
            //    //email_DisbursementList(headID,representativeID,srfd.SRFID); Function from e-mail controller
            //}
        }

        public List<SRF> getAllSRFs()
        {
            InvManagementEntities em = new InvManagementEntities();
            return em.SRFs.ToList<SRF>();
        }

        public void ChangeStatus(int srtID)
        {
            SRF s = ime.SRFs.Where(e => e.SRFID == srtID).First();
            s.StatusforForm = "Disbursed";
            ime.SaveChanges();
        }


    
    }
}
